use windows_sys::{
    Win32::Foundation::*, Win32::Graphics::Gdi::*, Win32::System::LibraryLoader::*,
    Win32::UI::Controls::*, Win32::UI::WindowsAndMessaging::*, core::*,
};

fn instance() -> HMODULE {
    unsafe { GetModuleHandleW(core::ptr::null()) }
}

fn main() {
    unsafe {
        let window_class = w!("window");

        // 填充窗口类结构体
        let wc = WNDCLASSW {
            hCursor: LoadCursorW(core::ptr::null_mut(), IDC_ARROW),
            hInstance: instance(),
            lpszClassName: window_class,
            style: CS_HREDRAW | CS_VREDRAW,
            lpfnWndProc: Some(wndproc),
            cbClsExtra: 0,
            cbWndExtra: 0,
            hIcon: core::ptr::null_mut(),
            hbrBackground: core::ptr::null_mut(),
            lpszMenuName: core::ptr::null(),
        };

        // 注册窗口类
        let atom = RegisterClassW(&wc);
        debug_assert!(atom != 0);

        // 创建窗口
        let window = CreateWindowExW(
            0,
            window_class,
            w!("这是一个简单的窗口"),
            WS_OVERLAPPEDWINDOW | WS_VISIBLE,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            core::ptr::null_mut(),
            core::ptr::null_mut(),
            instance(),
            core::ptr::null(),
        );
        debug_assert!(!window.is_null());

        // 显示窗口
        ShowWindow(window, SW_SHOW);
        UpdateWindow(window);

        // 消息循环
        let mut message = std::mem::zeroed();
        while GetMessageW(&mut message, core::ptr::null_mut(), 0, 0) != 0 {
            TranslateMessage(&message);
            DispatchMessageW(&message);
        }
    }
}

extern "system" fn wndproc(window: HWND, message: u32, wparam: WPARAM, lparam: LPARAM) -> LRESULT {
    unsafe {
        match message {
            WM_PAINT => {
                println!("WM_PAINT");
                let mut ps = PAINTSTRUCT::default();
                let hdc = BeginPaint(window, &mut ps);
                // TODO: 这里可以进行绘制操作
                let sys_brush = GetSysColorBrush(COLOR_WINDOW);
                FillRect(hdc, &ps.rcPaint, sys_brush);
                EndPaint(window, &ps);
                0
            }
            WM_DESTROY => {
                println!("WM_DESTROY");
                PostQuitMessage(0);
                0
            }
            _ => DefWindowProcW(window, message, wparam, lparam),
        }
    }
}
